using System;
using System.Collections.Specialized;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Security.Permissions;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.Utilities;

using EF;

namespace EF.Features.FeatureEFSimpleReminder
{
    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>

    [Guid("4db19353-f2fb-4eaf-8658-06bd1634478e")]
    public class FeatureEFSimpleReminderEventReceiver : SPFeatureReceiver
    {
        public void logInfo(string strMessage)
        {
            EFSimpleReminder.logTraceInfo(strMessage);
        }

        public void logDebugInfo(string strMessage)
        {
#if DEBUG
            EFSimpleReminder.logTraceInfo(strMessage);
#endif
        }
        
        //public void logInfo(SPWeb objSPWeb, string strMessage)
        //{
        //    SimpleReminder.logInfo(objSPWeb, strMessage, this.GetType().Assembly);
        //}

        // Uncomment the method below to handle the event raised after a feature has been activated.

        public static string AddWebPartPage(string strFileName, string strFileTitle, SPWeb objSPWeb, SPList objSPList, int iWebPartPageTemplate, string strPageType, string strFolderPath)
        {
            SPFile objSPFile = null;
            string postInformation =
            @"<?xml version=""1.0"" encoding=""UTF-8""?>" +
            @"<Method>" +
            @"<SetList Scope=""Request"">" + objSPList.ID + @"</SetList>" +
            @"<SetVar Name=""ID"">New</SetVar>" +
            @"<SetVar Name=""Cmd"">NewWebPage</SetVar>" +
            @"<SetVar Name=""Type"">" + strPageType + @"</SetVar>" +
            @"<SetVar Name=""WebPartPageTemplate"">" + iWebPartPageTemplate + @"</SetVar>" +
            @"<SetVar Name=""Title"">" + strFileName + @"</SetVar>" +
            @"<SetVar Name=""Overwrite"">true</SetVar>" +
            @"</Method>";
            string processBatch = objSPWeb.ProcessBatchData(postInformation);
            if (processBatch.Equals("<Result ID=\"\" Code=\"0\">\r\n</Result>\n", StringComparison.InvariantCultureIgnoreCase))
            {
                string strFileUrl = objSPList.RootFolder.Url + "/" + strFileName;
                if (strFileUrl.EndsWith(".aspx") == false)
                {
                    strFileUrl += ".aspx";
                }
                objSPFile = objSPWeb.GetFile(strFileUrl);
                //if page was in subfolder then move it there
                if (!String.IsNullOrEmpty(strFolderPath))
                {
                    objSPFile.MoveTo(strFileTitle, true);
                }
                SPFolder rootFolder = objSPFile.ParentFolder;

                using (SPLimitedWebPartManager spLimitedWebPartManager = objSPWeb.GetLimitedWebPartManager(strFileUrl, PersonalizationScope.Shared))
                {

                    foreach (System.Web.UI.WebControls.WebParts.WebPart objWebpart in spLimitedWebPartManager.WebParts)
                    {
                        if (objWebpart.ToString() == "Microsoft.SharePoint.WebPartPages.TitleBarWebPart")
                        {
                            TitleBarWebPart objTitleBarWebPart = (TitleBarWebPart)objWebpart;
                            objTitleBarWebPart.HeaderTitle = strFileTitle;
                            spLimitedWebPartManager.SaveChanges(objTitleBarWebPart);
                            break;
                        }
                    }
                    //System.Web.UI.WebControls.WebParts.WebPart objWebPart = spLimitedWebPartManager.WebParts["TitleBar"];
                    //objWebPart.Title = strFileTitle;
                    objSPWeb.Update();
                }

                return objSPFile.Url;
            }

            return string.Empty;
        }

        //  http://neganov.blogspot.com/2007/11/add-web-part-to-sharepoint-page.html
        public static ListViewWebPart AddListViewToPage(
            SPWeb objSPWeb,
            string pageUrl,
            SPView objSPView,
            string zoneID,
            int zoneIndex,
            string strWebPartTitle)
        {
            ListViewWebPart objListViewWebPart = null;
            string strListUrl = string.Empty;
            string strListViewWebPartID = string.Empty;
            if (string.IsNullOrEmpty(strWebPartTitle))
                strWebPartTitle = objSPView.ParentList.Title;

            using (SPLimitedWebPartManager spLimitedWebPartManager = objSPWeb.GetLimitedWebPartManager(pageUrl, PersonalizationScope.Shared))
            {
                using (objListViewWebPart = new ListViewWebPart())
                {
                    objListViewWebPart.ListName = objSPView.ParentList.ID.ToString("B").ToUpperInvariant();
                    objListViewWebPart.TitleUrl = objSPView.ServerRelativeUrl;
                    objListViewWebPart.WebId = objSPWeb.ID;
                    objListViewWebPart.Title = strWebPartTitle;
                    objListViewWebPart.ViewGuid = objSPView.ID.ToString();
                    //objListViewWebPart.DisplayTitle = "abcdefg";

                    spLimitedWebPartManager.AddWebPart(objListViewWebPart, zoneID, zoneIndex);

                    foreach (System.Web.UI.WebControls.WebParts.WebPart objWebpart in spLimitedWebPartManager.WebParts)
                    {
                        if (objWebpart.TitleUrl == objSPView.ServerRelativeUrl)
                        {
                            return (ListViewWebPart)objWebpart;
                        }
                    }
                }

                //return strListViewWebPartID;
                return null;
            }
        }

        public void initLists(SPSite site)
        {
            SPList splistConfiguration = null;
            SPList splistHistory = null;
            SPList splistTask = null;
            SPList splistJob = null;

            SPView oViewConfiguration = null;
            SPViewFieldCollection oViewFieldsConfiguration = null;

            SPView oViewHistory = null;
            SPViewFieldCollection oViewFieldsHistory = null;

            SPView oViewTask = null;
            //SPViewFieldCollection oViewFieldsTask = null;

            SPView oViewJob = null;
            SPViewFieldCollection oViewFieldsJob = null;

            string strViewQuery = string.Empty;
            string strViewQueryTemplate = string.Empty;
            StringCollection viewFields = null;

            splistConfiguration = site.RootWeb.Lists.TryGetList(EFSimpleReminder.Configuration_ListTitle);
            if (splistConfiguration != null)
            {
                splistConfiguration.Delete();
                splistConfiguration = null;
            }
            if (splistConfiguration == null)
            {
                Guid guidConfiguration = site.RootWeb.Lists.Add(EFSimpleReminder.Configuration_ListTitle, EFSimpleReminder.Configuration_ListDescription, SPListTemplateType.GenericList);
                splistConfiguration = site.RootWeb.Lists[guidConfiguration];

                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_RecurringType, SPFieldType.Choice, true);
                SPFieldChoice objSPFieldRecurringType = (SPFieldChoice)splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_RecurringType];
                objSPFieldRecurringType.Choices.Add(EFSimpleReminder.RecurringType_Monthly);
                objSPFieldRecurringType.Choices.Add(EFSimpleReminder.RecurringType_Weekly);
                objSPFieldRecurringType.Choices.Add(EFSimpleReminder.RecurringType_Daily);
                objSPFieldRecurringType.Choices.Add(EFSimpleReminder.RecurringType_Hourly);
                objSPFieldRecurringType.Choices.Add(EFSimpleReminder.RecurringType_Minutes);
                objSPFieldRecurringType.DefaultValue = EFSimpleReminder.RecurringType_Daily;
                objSPFieldRecurringType.Update();

                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_WebUrl, SPFieldType.Text, false);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ViewUrl, SPFieldType.Text, true);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSendTo, SPFieldType.Text, true);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderCC, SPFieldType.Text, false);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSubject, SPFieldType.Text, true);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderBody, SPFieldType.Note, false);
                SPFieldMultiLineText objSPFieldEmailBody = (SPFieldMultiLineText)splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderBody];
                objSPFieldEmailBody.RichText = false;
                objSPFieldEmailBody.RichTextMode = SPRichTextMode.Compatible;
                objSPFieldEmailBody.Update();
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_AppendHtmlTag, SPFieldType.Boolean, true);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_HtmlEncode, SPFieldType.Boolean, true);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_NotificationType, SPFieldType.MultiChoice, true);
                SPFieldMultiChoice objSPFieldNotificationType = (SPFieldMultiChoice)splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_NotificationType];
                objSPFieldNotificationType.Choices.Add(EFSimpleReminder.NotificationType_Email);
                objSPFieldNotificationType.Choices.Add(EFSimpleReminder.NotificationType_Task);
                objSPFieldNotificationType.DefaultValue = EFSimpleReminder.NotificationType_Task;
                objSPFieldNotificationType.Update();
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_TasksListTitle, SPFieldType.Text, false);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_LastScanTime, SPFieldType.DateTime, false);
                SPFieldDateTime objSPFieldLastScanTime = (SPFieldDateTime)splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_LastScanTime];
                objSPFieldLastScanTime.DisplayFormat = SPDateTimeFieldFormatType.DateTime;
                objSPFieldLastScanTime.Update();
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderFrequency, SPFieldType.Choice, true);
                SPFieldChoice objSPFieldEmailFrequency = (SPFieldChoice)splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderFrequency];
                objSPFieldEmailFrequency.Choices.Add(EFSimpleReminder.ReminderFrequency_Everytime);
                objSPFieldEmailFrequency.Choices.Add(EFSimpleReminder.ReminderFrequency_OneTimeOnly);
                objSPFieldEmailFrequency.DefaultValue = EFSimpleReminder.ReminderFrequency_Everytime;
                objSPFieldEmailFrequency.Update();
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_LastScanCount, SPFieldType.Number, false);
                splistConfiguration.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_IsActive, SPFieldType.Boolean, false);
                SPFieldBoolean objSPFieldIsActive = (SPFieldBoolean)splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_IsActive];
                objSPFieldIsActive.DefaultValue = @"1";
                objSPFieldIsActive.Update();

                splistConfiguration.EnableAttachments = false;
                splistConfiguration.Update();

                oViewConfiguration = splistConfiguration.DefaultView;
                oViewFieldsConfiguration = oViewConfiguration.ViewFields;
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_RecurringType]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_NotificationType]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_WebUrl]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_ViewUrl]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSendTo]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSubject]);
                //oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_EmailBody]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_AppendHtmlTag]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_HtmlEncode]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_IsActive]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_LastScanCount]);
                oViewFieldsConfiguration.Add(splistConfiguration.Fields[EFSimpleReminder.Column_EFSimpleReminderCfg_LastScanTime]);

                oViewConfiguration.TabularView = false;
                oViewConfiguration.Update();

                viewFields = new StringCollection();
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_RecurringType);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_NotificationType);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_WebUrl);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ViewUrl);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSendTo);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSubject);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_AppendHtmlTag);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_HtmlEncode);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_AppendHtmlTag);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_IsActive);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_LastScanCount);
                viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderCfg_LastScanTime);

                strViewQueryTemplate = @"<Eq><FieldRef Name='" + EFSimpleReminder.Column_EFSimpleReminderCfg_RecurringType + @"' /><Value Type='Choice'>{0}</Value></Eq>";
                strViewQueryTemplate += @"<Eq><FieldRef Name='IsActive' /><Value Type='Boolean'>1</Value></Eq>";
                strViewQueryTemplate = @"<Where><And>" + strViewQueryTemplate + @"</And></Where>";
                strViewQuery = string.Format(strViewQueryTemplate, EFSimpleReminder.RecurringType_Monthly);
                oViewConfiguration = splistConfiguration.Views.Add(EFSimpleReminder.RecurringType_Monthly, viewFields, strViewQuery, 30, true, false);
                oViewConfiguration.TabularView = false;
                oViewConfiguration.Update();
                strViewQuery = string.Format(strViewQueryTemplate, EFSimpleReminder.RecurringType_Weekly);
                oViewConfiguration = splistConfiguration.Views.Add(EFSimpleReminder.RecurringType_Weekly, viewFields, strViewQuery, 30, true, false);
                oViewConfiguration.TabularView = false;
                oViewConfiguration.Update();
                strViewQuery = string.Format(strViewQueryTemplate, EFSimpleReminder.RecurringType_Daily);
                oViewConfiguration = splistConfiguration.Views.Add(EFSimpleReminder.RecurringType_Daily, viewFields, strViewQuery, 30, true, false);
                oViewConfiguration.TabularView = false;
                oViewConfiguration.Update();
                strViewQuery = string.Format(strViewQueryTemplate, EFSimpleReminder.RecurringType_Hourly);
                oViewConfiguration = splistConfiguration.Views.Add(EFSimpleReminder.RecurringType_Hourly, viewFields, strViewQuery, 30, true, false);
                oViewConfiguration.TabularView = false;
                oViewConfiguration.Update();
                strViewQuery = string.Format(strViewQueryTemplate, EFSimpleReminder.RecurringType_Minutes);
                oViewConfiguration = splistConfiguration.Views.Add(EFSimpleReminder.RecurringType_Minutes, viewFields, strViewQuery, 30, true, false);
                oViewConfiguration.TabularView = false;
                oViewConfiguration.Update();

                //add test data
                SPListItem itemConfiguration = splistConfiguration.AddItem();
                itemConfiguration[SPBuiltInFieldId.Title] = @"test 1";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_RecurringType] = EFSimpleReminder.RecurringType_Daily;
                SPFieldMultiChoiceValue itemNotificationType = new SPFieldMultiChoiceValue();
                itemNotificationType.Add(EFSimpleReminder.NotificationType_Email);
                itemNotificationType.Add(EFSimpleReminder.NotificationType_Task);
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_NotificationType] = itemNotificationType;
                
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_WebUrl] = @"";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ViewUrl] = @"Lists/testList1/AllItems.aspx";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSendTo] = @"[Created By]";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderCC] = @"yyy@gmail.com;[Modified By]";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSubject] = @"Hello from 'test 1' - Title=[Title]";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderBody] = string.Format(@"This is a test reminder from EF{0}{0}ID=[ID],{0}Title=[Title],{0}Created=[Created],{0}Created By=[Created By],{0}Modified=[Modified],{0}ModifiedBy=[Modified By]", Environment.NewLine);
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_AppendHtmlTag] = true;
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_HtmlEncode] = true;
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_TasksListTitle] = @"Tasks";
                itemConfiguration.Update();

                itemConfiguration = splistConfiguration.AddItem();
                itemConfiguration[SPBuiltInFieldId.Title] = @"test 2";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_RecurringType] = EFSimpleReminder.RecurringType_Hourly;
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_WebUrl] = @"subsite1";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ViewUrl] = @"Lists/testList2/AllItems.aspx";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSendTo] = @"[Created By]";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderCC] = @"yyy@gmail.com;[Modified By]";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderSubject] = @"Hello from 'test 2' - Title=[Title]";
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_ReminderBody] = string.Format(@"This is a test reminder from EF{0}{0}ID=[ID],{0}Title=[Title],{0}Created=[Created],{0}Created By=[Created By],{0}Modified=[Modified],{0}ModifiedBy=[Modified By]", Environment.NewLine);
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_AppendHtmlTag] = true;
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_HtmlEncode] = true;
                itemConfiguration[EFSimpleReminder.Column_EFSimpleReminderCfg_TasksListTitle] = @"Tasks";
                itemConfiguration.Update();
            }

            //make sure the history list is already created
            splistHistory = site.RootWeb.Lists.TryGetList(EFSimpleReminder.History_ListTitle);
            if (splistHistory != null)
                splistHistory.Delete();

            Guid guidHistory = site.RootWeb.Lists.Add(EFSimpleReminder.History_ListTitle, EFSimpleReminder.History_ListDescription, SPListTemplateType.GenericList);
            splistHistory = site.RootWeb.Lists[guidHistory];
            splistHistory.EnableAttachments = false;
            splistHistory.Update();

            splistHistory.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_WebTitle, SPFieldType.Note, false);
            SPFieldMultiLineText objSPFieldWebTitle = (SPFieldMultiLineText)splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_WebTitle];
            objSPFieldWebTitle.RichText = false;
            objSPFieldWebTitle.RichTextMode = SPRichTextMode.Compatible;
            objSPFieldWebTitle.Update();
            splistHistory.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ListTitle, SPFieldType.Text, false);
            splistHistory.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ItemId, SPFieldType.Number, false);
            splistHistory.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ReminderSubject, SPFieldType.Text, false);
            splistHistory.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ReminderSendTo, SPFieldType.Text, false);
            splistHistory.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ReminderCC, SPFieldType.Text, false);
            splistHistory.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ItemUrl, SPFieldType.Text, false);
            splistHistory.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_TaskUrl, SPFieldType.Text, false);

            oViewHistory = splistHistory.DefaultView;
            oViewFieldsHistory = oViewHistory.ViewFields;
            oViewFieldsHistory.Add(splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_WebTitle]);
            oViewFieldsHistory.Add(splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_ListTitle]);
            oViewFieldsHistory.Add(splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_ItemId]);
            oViewFieldsHistory.Add(splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_ReminderSubject]);
            oViewFieldsHistory.Add(splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_ReminderSendTo]);
            oViewFieldsHistory.Add(splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_ReminderCC]);
            oViewFieldsHistory.Add(splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_ItemUrl]);
            oViewFieldsHistory.Add(splistHistory.Fields[EFSimpleReminder.Column_EFSimpleReminderHistory_TaskUrl]);
            //oViewHistory.TabularView = false;
            oViewHistory.Update();

            viewFields = new StringCollection();
            viewFields.Add(splistHistory.Fields[SPBuiltInFieldId.Modified].InternalName);
            viewFields.Add(splistHistory.Fields[SPBuiltInFieldId.Title].InternalName);
            viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_WebTitle);
            viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ListTitle);
            viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ReminderSubject);
            viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_ReminderSendTo);
            //viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderHistory_TaskUrl);

            strViewQueryTemplate = @"<Where><Gt><FieldRef Name='ID' /><Value Type='Counter'>0</Value></Gt></Where>";
            strViewQueryTemplate += @"<OrderBy><FieldRef Name='ID' Ascending='False' /></OrderBy>";
            strViewQuery = string.Format(strViewQueryTemplate);
            oViewHistory = splistHistory.Views.Add(EFSimpleReminder.View_Portal, viewFields, strViewQuery, 30, true, false);
            //oViewHistory.TabularView = false;
            oViewHistory.Update();

            //if the default task list is already created
            splistTask = site.RootWeb.Lists.TryGetList(EFSimpleReminder.TaskDefault_ListTitle);
            if (splistTask != null)
            {
                bool boolViewExist = false;
                foreach (SPView objSPViewCurrent in splistTask.Views)
                {
                    if (objSPViewCurrent.Title == EFSimpleReminder.View_Portal)
                    {
                        boolViewExist = true;
                        break;
                    }
                }
                if (boolViewExist == false)
                {
                    viewFields = new StringCollection();
                    viewFields.Add(splistTask.Fields[SPBuiltInFieldId.Modified].InternalName);
                    viewFields.Add(splistTask.Fields[SPBuiltInFieldId.AssignedTo].InternalName);
                    viewFields.Add(splistTask.Fields[SPBuiltInFieldId.LinkTitle].InternalName);
                    //viewFields.Add(splistTask.Fields[SPBuiltInFieldId.Body].InternalName);

                    strViewQueryTemplate = @"<Where><Gt><FieldRef Name='ID' /><Value Type='Counter'>0</Value></Gt></Where>";
                    strViewQueryTemplate += @"<OrderBy><FieldRef Name='ID' Ascending='False' /></OrderBy>";
                    strViewQuery = string.Format(strViewQueryTemplate);
                    oViewTask = splistTask.Views.Add(EFSimpleReminder.View_Portal, viewFields, strViewQuery, 30, true, false);
                    oViewTask.TabularView = true;
                    oViewTask.Update();
                }
            }

            //make sure the job list is already created
            splistJob = site.RootWeb.Lists.TryGetList(EFSimpleReminder.Job_ListTitle);
            if (splistJob != null)
                splistJob.Delete();

            Guid guidJob = site.RootWeb.Lists.Add(EFSimpleReminder.Job_ListTitle, EFSimpleReminder.Job_ListDescription, SPListTemplateType.GenericList);
            splistJob = site.RootWeb.Lists[guidJob];
            splistJob.Fields.Add(EFSimpleReminder.Column_EFSimpleReminderJob_AdminLink, SPFieldType.URL, false);
            splistJob.EnableAttachments = false;
            splistJob.Update();

            oViewJob = splistJob.DefaultView;
            oViewFieldsJob = oViewJob.ViewFields;
            oViewFieldsJob.Add(splistJob.Fields[EFSimpleReminder.Column_EFSimpleReminderJob_AdminLink]);
            oViewJob.Update();

            viewFields = new StringCollection();
            viewFields.Add(EFSimpleReminder.Column_EFSimpleReminderJob_AdminLink);

            oViewJob = splistJob.Views.Add(EFSimpleReminder.View_Portal, viewFields, strViewQuery, 30, true, false);
            oViewJob.TabularView = false;
            oViewJob.Update();
        }

        public void initAdminPage(SPSite site)
        {
            SPDocumentLibrary spDocPageLib = null;

            SPWeb objSPWeb = site.RootWeb;
            Guid guidSitePages = Guid.Empty;
            SPList objSPList = objSPWeb.Lists.TryGetList(EFSimpleReminder.DocLib_SitePages_Title);
            if (objSPList == null)
            {
                guidSitePages = objSPWeb.Lists.Add(EFSimpleReminder.DocLib_SitePages_PathName, "", SPListTemplateType.DocumentLibrary);
                objSPList = objSPWeb.Lists[guidSitePages];
                objSPList.Title = EFSimpleReminder.DocLib_SitePages_Title;
                objSPList.Update();
            }
            else
            {
                guidSitePages = objSPList.ID;
                foreach (SPListItem item in objSPList.Items)
                {
                    if (item.File.Name.StartsWith(EFSimpleReminder.AdminPage_Name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        item.Delete();
                        break;
                    }
                }
            }
            spDocPageLib = (SPDocumentLibrary)objSPWeb.Lists[guidSitePages];

            string strPageUrl = AddWebPartPage(EFSimpleReminder.AdminPage_Name, EFSimpleReminder.AdminPage_Title, objSPWeb, spDocPageLib, 2, "WebPartPage", "");
            SPFile currentWebPartPage = objSPWeb.GetFile(strPageUrl);

            ListViewWebPart objListViewWebPart = null;

            try
            {
                objSPList = objSPWeb.Lists.TryGetList(EFSimpleReminder.Configuration_ListTitle);
                if (objSPList == null)
                    throw new ArgumentException("List(" + EFSimpleReminder.Configuration_ListTitle + ") not found.");
                logDebugInfo(string.Format(@"ConfigurationView.Title={0}, ConfigurationView.Url={1}", objSPList.DefaultView.Title, objSPList.DefaultView.Url));
                objListViewWebPart = AddListViewToPage(objSPWeb, strPageUrl, objSPList.DefaultView, EFSimpleReminder.Zone_Header, 1, @"Scheduled reminder list");
                EFSimpleReminder.SetToolbarTypeFreeForm(objSPWeb, strPageUrl, objListViewWebPart.StorageKey);

                objSPList = objSPWeb.Lists.TryGetList(EFSimpleReminder.History_ListTitle);
                if (objSPList == null)
                    throw new ArgumentException("List(" + EFSimpleReminder.History_ListTitle + ") not found.");
                logDebugInfo(string.Format(@"HistoryView.Title={0}, HistoryView.Url={1}", objSPList.Views[EFSimpleReminder.View_Portal].Title, objSPList.Views[EFSimpleReminder.View_Portal].Url));
                objListViewWebPart = AddListViewToPage(objSPWeb, strPageUrl, objSPList.Views[EFSimpleReminder.View_Portal], EFSimpleReminder.Zone_Footer, 1, @"Reminder history");

                objSPList = objSPWeb.Lists.TryGetList(EFSimpleReminder.TaskDefault_ListTitle);
                if (objSPList == null)
                    throw new ArgumentException("List(" + EFSimpleReminder.TaskDefault_ListTitle + ") not found.");
                logDebugInfo(string.Format(@"TaskView.Title={0}, TaskView.Url={1}", objSPList.Views[EFSimpleReminder.View_Portal].Title, objSPList.Views[EFSimpleReminder.View_Portal].Url));
                objListViewWebPart = AddListViewToPage(objSPWeb, strPageUrl, objSPList.Views[EFSimpleReminder.View_Portal], EFSimpleReminder.Zone_LeftColumn, 1, @"Reminder Tasks");
                //EFSimpleReminder.ShowToolbar(objSPWeb, strPageUrl, objListViewWebPart.StorageKey);

                objSPList = objSPWeb.Lists.TryGetList(EFSimpleReminder.Job_ListTitle);
                if (objSPList == null)
                    throw new ArgumentException("List(" + EFSimpleReminder.Job_ListTitle + ") not found.");
                logDebugInfo(string.Format(@"JobView.Title={0}, JobView.Url={1}", objSPList.Views[EFSimpleReminder.View_Portal].Title, objSPList.Views[EFSimpleReminder.View_Portal].Url));
                objListViewWebPart = AddListViewToPage(objSPWeb, strPageUrl, objSPList.Views[EFSimpleReminder.View_Portal], EFSimpleReminder.Zone_RightColumn, 1, @"Reminder Jobs");
            }
            catch (Exception ex)
            {
                logInfo(string.Format(@"ex.Message={0}", ex.Message));
                logInfo(string.Format(@"ex.StackTrace={0}", ex.StackTrace));

                throw;
            }
        }

        public void initJobs(SPSite objSPSite)
        {
            string strJobName = string.Empty;
            string strJobUrl = string.Empty;
            SPList splistJob = objSPSite.RootWeb.Lists.TryGetList(EFSimpleReminder.Job_ListTitle);
            SPListItem objSPListItemJob = null;

            string[] strArrayRecurringType = { EFSimpleReminder.RecurringType_Monthly, EFSimpleReminder.RecurringType_Weekly, EFSimpleReminder.RecurringType_Daily, EFSimpleReminder.RecurringType_Hourly, EFSimpleReminder.RecurringType_Minutes };
            foreach (string strRecurringType in strArrayRecurringType)
            {
                strJobName = EFSimpleReminder.getFullJobName(objSPSite.Url, strRecurringType);

                // make sure the job isn't already registered
                foreach (SPJobDefinition job in objSPSite.WebApplication.JobDefinitions)
                {
                    //if (job.Name.StartsWith(JOB_NAME, StringComparison.InvariantCultureIgnoreCase))
                    if (job.Name.Equals(strJobName, StringComparison.InvariantCultureIgnoreCase))
                        job.Delete();
                }

                EFSimpleReminder listLoggerJob = new EFSimpleReminder(strJobName, objSPSite.WebApplication);

                switch (strRecurringType)
                {
                    case EFSimpleReminder.RecurringType_Monthly:
                        SPMonthlyByDaySchedule scheduleMonthly = new SPMonthlyByDaySchedule();
                        scheduleMonthly.BeginWeek = WeekOfMonth.First;
                        scheduleMonthly.BeginDay = DayOfWeek.Monday;
                        scheduleMonthly.BeginHour = 1;
                        scheduleMonthly.BeginMinute = 0;
                        listLoggerJob.Schedule = scheduleMonthly;
                        break;
                    case EFSimpleReminder.RecurringType_Weekly:
                        SPWeeklySchedule scheduleWeekly = new SPWeeklySchedule();
                        scheduleWeekly.BeginDayOfWeek = DayOfWeek.Monday;
                        scheduleWeekly.BeginHour = 0;
                        scheduleWeekly.BeginMinute = 0;
                        scheduleWeekly.EndDayOfWeek = DayOfWeek.Monday;
                        scheduleWeekly.EndHour = 1;
                        scheduleWeekly.EndMinute = 59;
                        listLoggerJob.Schedule = scheduleWeekly;
                        break;
                    case EFSimpleReminder.RecurringType_Daily:
                        SPDailySchedule scheduleDaily = new SPDailySchedule();
                        scheduleDaily.BeginHour = 0;
                        scheduleDaily.EndHour = 1;
                        listLoggerJob.Schedule = scheduleDaily;
                        break;
                    case EFSimpleReminder.RecurringType_Hourly:
                        SPHourlySchedule scheduleHourly = new SPHourlySchedule();
                        scheduleHourly.BeginMinute = 0;
                        scheduleHourly.EndMinute = 10;
                        listLoggerJob.Schedule = scheduleHourly;
                        break;
                    case EFSimpleReminder.RecurringType_Minutes:
                        SPMinuteSchedule scheduleMinutes = new SPMinuteSchedule();
                        scheduleMinutes.Interval = 10;
                        listLoggerJob.Schedule = scheduleMinutes;
                        break;
                    default:
                        logInfo(string.Format(@"initJobs(), invalid strRecurringType={0}, strJobName={1}", strRecurringType, strJobName));
                        break;
                }

                listLoggerJob.Update(true);

                if (splistJob != null)
                {
                    objSPListItemJob = splistJob.AddItem();
                    objSPListItemJob[SPBuiltInFieldId.Title] = strJobName;
                    //   http://hvsp2010a:9000/_admin/JobEdit.aspx?JobId=c936e330%2D54a7%2D4314%2D9a68%2D3178934638dc
                    SPAdministrationWebApplication centralWebApp = SPAdministrationWebApplication.Local;
                    strJobUrl = string.Format("{0}/_admin/JobEdit.aspx?JobId={1}&Source={2}", centralWebApp.Sites[0].Url, listLoggerJob.Id, SPEncode.UrlEncode(objSPSite.Url + @"/" + EFSimpleReminder.AdminPage_Url));
                    //logInfo(string.Format(@"strJobName={0}, JobUrl={1}", strJobName, strJobUrl));
                    objSPListItemJob[EFSimpleReminder.Column_EFSimpleReminderJob_AdminLink] = string.Format("{0}, {1}", strJobUrl, strRecurringType);
                    objSPListItemJob.Update();
                }

                logInfo(string.Format(@"Job ({0}) created.", listLoggerJob.Title));
            }
        }

        //  http://neganov.blogspot.com/2007/11/add-web-part-to-sharepoint-page.html
        public string AddWebPartToPage(
            SPWeb web,
            string pageUrl,
            string webPartName,
            string zoneID,
            int zoneIndex)
        {
            using (System.Web.UI.WebControls.WebParts.WebPart webPart = CreateWebPart(web, webPartName))
            {
                using (SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(pageUrl, PersonalizationScope.Shared))
                {
                    manager.AddWebPart(webPart, zoneID, zoneIndex);
                    return webPart.ID;
                }
            }
        }

        private System.Web.UI.WebControls.WebParts.WebPart CreateWebPart(SPWeb web, string webPartName)
        {
            SPQuery query = new SPQuery();
            query.Query = String.Format(
                "<Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='File'>{0}</Value></Eq></Where>",
                webPartName);

            SPList webPartGallery = null;

            if (null == web.ParentWeb)
            {
                // This is the root web.
                webPartGallery = web.GetCatalog(SPListTemplateType.WebPartCatalog);
            }
            else
            {
                // This is a sub-web.
                webPartGallery = web.ParentWeb.GetCatalog(SPListTemplateType.WebPartCatalog);
            }

            SPListItemCollection webParts = webPartGallery.GetItems(query);

            string typeName = webParts[0].GetFormattedValue("WebPartTypeName");
            string assemblyName = webParts[0].GetFormattedValue("WebPartAssembly");
            ObjectHandle webPartHandle = Activator.CreateInstance(assemblyName, typeName);

            System.Web.UI.WebControls.WebParts.WebPart webPart =
                (System.Web.UI.WebControls.WebParts.WebPart)webPartHandle.Unwrap();
            return webPart;
        }

        public object ConvertValue(string propertyValue, PropertyInfo property)
        {
            if (propertyValue != string.Empty)
            {
                object value = Convert.ChangeType(propertyValue, property.PropertyType);
                return value;
            }

            return null;
        }

        public void SetWebPartProperty(
            SPWeb web,
            string pageUrl,
            string webPartID,
            string propertyName,
            string propertyValue)
        {
            using (SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(pageUrl, PersonalizationScope.Shared))
            {
                System.Web.UI.WebControls.WebParts.WebPart part = manager.WebParts[webPartID];
                Type runtimeType = part.GetType();
                PropertyInfo property = runtimeType.GetProperty(propertyName);
                object value = ConvertValue(propertyValue, property);
                property.SetValue(part, value, null);
                manager.SaveChanges(part);
            }
        }

        public void AddWebPartConnection(
            SPWeb web,
            string pageUrl,
            string providerWebPartID,
            string consumerWebPartID,
            string providerConnectionPointName,
            string consumerConnectionPointName)
        {
            using (SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(pageUrl, PersonalizationScope.Shared))
            {
                System.Web.UI.WebControls.WebParts.WebPart provider = manager.WebParts[providerWebPartID];
                System.Web.UI.WebControls.WebParts.WebPart consumer = manager.WebParts[consumerWebPartID];

                ProviderConnectionPointCollection providerPoints = manager.GetProviderConnectionPoints(provider);
                ConsumerConnectionPointCollection consumerPoints = manager.GetConsumerConnectionPoints(consumer);

                ProviderConnectionPoint providerPoint = null;

                foreach (ProviderConnectionPoint point in providerPoints)
                {
                    if (String.Equals(providerConnectionPointName, point.DisplayName, StringComparison.OrdinalIgnoreCase))
                    {
                        providerPoint = point;
                        break;
                    }
                }

                ConsumerConnectionPoint consumerPoint = null;

                foreach (ConsumerConnectionPoint point in consumerPoints)
                {
                    if (String.Equals(consumerConnectionPointName, point.DisplayName, StringComparison.OrdinalIgnoreCase))
                    {
                        consumerPoint = point;
                        break;
                    }
                }

                manager.SPConnectWebParts(provider, providerPoint, consumer, consumerPoint);
            }
        }

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPSite site = properties.Feature.Parent as SPSite;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite objSPSite = new SPSite(site.ID))
                {
                    using (SPWeb objSPWeb = objSPSite.RootWeb)
                    {
                        try
                        {
                            initLists(objSPSite);
                            initJobs(objSPSite);
                            initAdminPage(objSPSite);

                            logInfo("Feature activated.");
                        }
                        catch (Exception ex)
                        {
                            logInfo(string.Format(@"ex.Message={0}", ex.Message));
                            logInfo(string.Format(@"ex.StackTrace={0}", ex.StackTrace));
                            throw;
                        }
                    }
                }
            });
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPSite site = properties.Feature.Parent as SPSite;
            SPList splist = null;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite objSPSite = new SPSite(site.ID))
                {
                    using (SPWeb objSPWeb = objSPSite.RootWeb)
                    {
                        //string strWebTitle = objSPWeb.Title;
                        foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
                        {
                            if (job.Name.StartsWith(EFSimpleReminder.AdminPage_Name, StringComparison.InvariantCultureIgnoreCase))
                            {
                                logInfo(@"Feature deactivated. Job (" + job.Name + ") deleted.");
                                job.Delete();
                            }
                        }

                        splist = objSPWeb.Lists.TryGetList(EFSimpleReminder.History_ListTitle);
                        if (splist != null)
                        {
                            splist.Delete();
                            logInfo(@"Feature deactivated. List (" + EFSimpleReminder.History_ListTitle + ") deleted.");
                        }

                        splist = objSPWeb.Lists.TryGetList(EFSimpleReminder.Job_ListTitle);
                        if (splist != null)
                        {
                            splist.Delete();
                            logInfo(@"Feature deactivated. List (" + EFSimpleReminder.Job_ListTitle + ") deleted.");
                        }

                        //delete admin page
                        splist = objSPWeb.Lists.TryGetList(EFSimpleReminder.DocLib_SitePages_Title);
                        if (splist != null)
                        {
                            foreach (SPListItem item in splist.Items)
                            {
                                if (item.File.Name.StartsWith(EFSimpleReminder.AdminPage_Name, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    item.Delete();
                                    break;
                                }
                            }
                        }
                        logInfo(string.Format("Admin page ({0}) deleted.", EFSimpleReminder.AdminPage_Url));
                    }
                }
            });
        }

        // Uncomment the method below to handle the event raised after a feature has been installed.

        //public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        //{
        //}


        // Uncomment the method below to handle the event raised before a feature is uninstalled.

        //public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        //{
        //}

        // Uncomment the method below to handle the event raised when a feature is upgrading.

        //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        //{
        //}
    }
}
